package org.smr.ministore.service.impl;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

import org.apache.commons.collections.CollectionUtils;
import org.blade.dao.base.BaseMapper;
import org.blade.msg.ErrorCode;
import org.blade.utils.IdGenUtils;
import org.blade.utils.Pager;
import org.blade.service.base.AbstractService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.smr.ministore.dao.GoodsMapper;
import org.smr.ministore.dao.GoodsOrganMapper;
import org.smr.ministore.entities.Goods;
import org.smr.ministore.entities.GoodsOrgan;
import org.smr.ministore.entities.GoodsTypeOrgan;
import org.smr.ministore.entities.vo.Assign2OrganVO;
import org.smr.ministore.entities.vo.Assign2OrgansVO;
import org.smr.ministore.entities.vo.GoodsVO;
import org.smr.ministore.entities.vo.OrganVO;
import org.smr.ministore.service.GoodsService;

import org.springframework.beans.factory.annotation.Autowired;


import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service("goodsServiceImpl")
@Transactional(readOnly = false)
public class GoodsServiceImpl extends AbstractService<Long, Goods> implements GoodsService {


    private static Logger logger = LoggerFactory.getLogger(GoodsServiceImpl.class);

    @Autowired
    private GoodsMapper mapper;

    @Autowired
    private GoodsOrganMapper goodsOrganMapper;

    @Autowired
    public GoodsServiceImpl(GoodsMapper mapper) {
        super(mapper);
    }

    public int save(Goods entity) {
        super.saveAttatch(entity);
        int effectCount = mapper.insert(entity);
        GoodsOrgan goodsOrgan = this.assignee(entity);
        IdGenUtils.saveAttatch(goodsOrgan);
        effectCount = +goodsOrganMapper.insert(goodsOrgan);
        return effectCount;
    }

    private GoodsOrgan assignee(Goods entity) {
        return entity.assignTo(entity.getAssignee());
    }

    public int updateById(Goods id) {
        super.modifyAttach(id);

        return mapper.updateById(id);
    }

    @Transactional(readOnly = true)
    public Goods queryById(Long id) {
        return mapper.selectById(id);
    }

    public int deleteById(Long id) {

        return mapper.deleteById(id);
    }

    @Transactional(readOnly = true)
    public Pager<Goods> paginate(Goods entity, Long pageSize, Long pageNum) {

        Pager<Goods> pager = new Pager(pageSize, pageNum);
        List list = mapper.queryGoodsPagination(entity, entity.getOrganIds(),  pager);
        pager.setEntities(list);
        return pager;
    }

    public int batchSave(List<Goods> entities) {
        this.batchSaveAttatch(entities);
        return mapper.batchInsert(entities);
    }


    public int batchModify(List<Goods> entities) {
        this.batchModifyAttatch(entities);
        return mapper.batchUpdate(entities);
    }


    public int deleteByIdLogical(Long id) {
        Goods goods = new Goods();
        GoodsVO goodsCondition = new GoodsVO();
        goodsCondition.setId(id);
        List<GoodsOrgan> goodsOrgans =  goodsOrganMapper.selectByGoodsId(goodsCondition);
        goods.setReferences(goodsOrgans);
        if (!goods.hasReference()) {
            return mapper.deleteById(id);
        }
        return ErrorCode.Persistence.NONE_EFFECT;
    }

    public int assign(Assign2OrganVO assign2Organ) {
        if(Objects.isNull(assign2Organ)){
            return ErrorCode.Persistence.NONE_EFFECT;
        }
        Goods goods = new Goods();
        List<GoodsOrgan> goodsOrgans = goods.assignTo(assign2Organ);
        if(CollectionUtils.isEmpty(goodsOrgans)) {
            return ErrorCode.Persistence.NONE_EFFECT;
        }
        IdGenUtils.batchSaveAttach(goodsOrgans);
        return this.goodsOrganMapper.batchInsert(goodsOrgans);
    }

    @Override
    public List<GoodsOrgan> queryGoodsAssignee(Assign2OrgansVO assignee) {
        GoodsOrgan goodsOrgan = new GoodsOrgan();
        GoodsVO goodsVO = goodsOrgan.queryAssignee(assignee);
        return goodsOrganMapper.selectByGoodsId(goodsVO);
    }

    @Transactional(readOnly = true)
    public Goods queryByPrimaryKey(Goods goods) {
        return mapper.selectByPrimaryKey(goods);
    }

    public int assign(Assign2OrgansVO assignee) {
        Goods goods = new Goods();
        goods.setCreateBy(assignee.getCreateBy());
        goods.setUpdateBy(assignee.getUpdateBy());

        List<GoodsOrgan> goodsOrgansPersistence = this.goodsOrganMapper.selectBy(assignee);

        goods.want2Assign(goodsOrgansPersistence, assignee);
        if (CollectionUtils.isEmpty(assignee.getAssignees())) {
            return ErrorCode.Persistence.NONE_EFFECT;
        }
        if (!CollectionUtils.isEmpty(goodsOrgansPersistence)) {
            return ErrorCode.Persistence.NONE_EFFECT;
        }
        List<GoodsOrgan> goodsOrgans = goods.assignTo(assignee);
        IdGenUtils.batchSaveAttach(goodsOrgans);
        return this.goodsOrganMapper.batchInsert(goodsOrgans);
    }


    @Override
    public Long getId() {
        return IdGenUtils.getNextLongId();
    }
}
